package com.daryl.sqlSession;


import com.daryl.config.Function;
import com.daryl.config.MapperBean;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class MyConfiguration {
    private static ClassLoader loader =  ClassLoader.getSystemClassLoader();

    public Connection build(String resource){
        try {
            InputStream stream = loader.getResourceAsStream(resource);
            SAXReader reader = new SAXReader();
            Document document = reader.read(stream);
            Element root = document.getRootElement();
            return evalDataSource(root);
        } catch (Exception e) {
           throw new RuntimeException("error occured while evaling xml"+resource);
        }
    }

    private Connection evalDataSource(Element node) throws ClassNotFoundException{
        if(!node.getName().equals("database")){
            throw new RuntimeException("root should be <database>");
        }
        String driverClassName = null;
        String url = null;
        String username = null;
        String password = null;
        for(Object item : node.elements("property")){
            Element i = (Element) item;
            String value = getValue(i);
            String name = i.attributeValue("name");
            if(name == null || value == null){
                throw new RuntimeException("database property should contain name and value");
            }
            if("url".equals(name)){
                url = value;
            }else if("username".equals(name)){
                username = value;
            }else if("driverClassName".equals(name)){
                driverClassName = value;
            }else if("password".equals(name)){
                password = value;
            }else{
                throw new RuntimeException("database property");
            }

        }
        Class.forName(driverClassName);
        Connection connection = null;
        try{
            connection = DriverManager.getConnection(url,username,password);
        }catch (SQLException e){
            e.printStackTrace();
        }
        return connection;

    }

    private String getValue(Element node){
        return node.hasContent()?node.getText():node.attributeValue("value");
    }

    public MapperBean readMapper(String path){
        MapperBean mapper = new MapperBean();
        try {
            InputStream stream = loader.getResourceAsStream(path);
            SAXReader reader  = new SAXReader();
            Document document = reader.read(stream);
            Element root = document.getRootElement();
            mapper.setInterfaceName(root.attributeValue("nameSpace").trim());
            List<Function> list = new ArrayList<Function>();
            for(Iterator rootIter = root.elementIterator(); rootIter.hasNext();){
                Function fun = new Function();
                Element e = (Element) rootIter.next();
                String sqltype = e.getName().trim();
                String funcName = e.attributeValue("id").trim();
                String sql = e.getText().trim();
                String resultType = e.attributeValue("resultType").trim();
                fun.setSqltype(sqltype);
                fun.setFuncName(funcName);
                Object newInstance = null;
                try {
                    newInstance = Class.forName(resultType).newInstance();
                } catch (InstantiationException e1) {
                    e1.printStackTrace();
                } catch (IllegalAccessException e1) {
                    e1.printStackTrace();
                } catch (ClassNotFoundException e1) {
                    e1.printStackTrace();
                }
                fun.setResultType(newInstance);
                fun.setSql(sql);
                list.add(fun);
            }
            mapper.setList(list);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return mapper;
    }

}
